﻿using LuShanTea.DTO;
using LuShanTea.IService;
using LuShanTea.Service.Entities;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace LuShanTea.Service
{
    public class OrderService : IOrderService
    {
        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="orderAddNewDTO"></param>
        /// <returns></returns>
        public long AddNew(OrderAddNewDTO orderAddNewDTO)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<IdName> idNameBaseService = new BaseService<IdName>(context);

                var status = idNameBaseService.GetAll()
                    .SingleOrDefault(s => s.TypeName == "订单状态" && s.Name == "未付款");

                Order order = new Order()
                {
                    AddressId = orderAddNewDTO.AddressId,
                    Amount = orderAddNewDTO.Amount,
                    ExpressId = orderAddNewDTO.ExpressId,
                    Guid = orderAddNewDTO.Guid,
                    StatusId = status.Id,
                    LeaveWord = orderAddNewDTO.LeaveWord,
                    PayWayId = orderAddNewDTO.PaywayId,
                    ReceiptId = orderAddNewDTO.ReceiptId,
                    UserId = orderAddNewDTO.UserId,

                };

                context.Orders.Add(order);
                context.SaveChanges();

                return order.Id;
            }
        }

        public OrderDTO GetById(long orderId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                var order = baseService.GetAll()
                        .Include(o => o.User).Include(o => o.Address)
                        .Include(o => o.Status).Include(o => o.Address.Area)
                        .Include(o => o.Address.Area.City).Include(o => o.Address.Area.City.Province)
                        .Include(o => o.Express).Include(o => o.PayWay)
                        .Include(o => o.Receipt).AsNoTracking().SingleOrDefault(o => o.Id == orderId);



                return order == null ? null : ToDTO(order);
            }
        }

        public bool IsAnyOrderByUser(long userId, long orderId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                return baseService.GetAll()
                    .Any(o => o.UserId == userId && o.Id == orderId);

            }
        }

        public OrderDTO[] GetPageDataOrder(int pageSize, int pageIndex)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                var orders = baseService.GetAll()
                        .Include(o => o.User).Include(o => o.Address)
                        .Include(o => o.Status)
                        .Include(o => o.Express).Include(o => o.PayWay)
                        .Include(o => o.Receipt).AsNoTracking().OrderBy(o => o.Id)
                        .Skip((pageIndex - 1) * pageSize).Take(pageSize);

                return orders.ToList().Select(o => ToDTO(o)).ToArray();
            }
        }

        /// <summary>
        /// 分页获取用户订单
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="currentIndex">当前页</param>
        /// <returns></returns>
        public OrderDTO[] GetPageDataOrderByUserId(long userId, int pageSize, int pageIndex)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                var user = context.Users.Where(u => u.Id == userId && !u.IsDeleted);

                if (user == null)
                {
                    return null;
                }

                var orders = baseService.GetAll().Where(o => o.UserId == userId)
                        .Include(o => o.User).Include(o => o.Address)
                        .Include(o => o.Status)
                        .Include(o => o.Express).Include(o => o.PayWay)
                        .Include(o => o.Receipt).AsNoTracking().OrderByDescending(o => o.CreateDateTime)
                        .Skip((pageIndex - 1) * pageSize).Take(pageSize);

                return orders.ToList().Select(o => ToDTO(o)).ToArray();
            }
        }

        public long GetCountByUser(long userId, long? statusId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                var orders = baseService.GetAll()
                    .Where(o => o.UserId == userId);

                if (statusId != null)
                {
                    orders = orders.Where(o => o.StatusId == statusId);
                }


                long totalCount = orders.LongCount();
                return totalCount;
            }
        }


        public long GetTotalCount()
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                long totalCount = baseService.GetAll().LongCount();

                return totalCount;
            }
        }

        /// <summary>
        /// 根据id软删除订单
        /// </summary>
        /// <param name="orderId">订单Id</param>
        public void MarkDeleted(long orderId)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                Order order = baseService.GetById(orderId);

                if (order == null)
                {
                    throw new ArgumentException(string.Format($"订单Id为：{orderId}不存在"));
                }

                baseService.MakeDelete(orderId);
            }
        }

        /// <summary>
        /// 获取用户day天的订单
        /// </summary>
        /// <param name="userId">；用户Id</param>
        /// <param name="day">天数</param>
        /// <returns></returns>
        public OrderDTO[] GetUserOrderToDay(long userId, int day)
        {

            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);

                var user = context.Users.Where(u => u.Id == userId && !u.IsDeleted);

                if (user == null)
                {
                    return null;
                }

                DateTime time = DateTime.Now.AddDays(-day);

                var orders = baseService.GetAll().Where(o => o.UserId == userId && o.CreateDateTime >= time)
                        .Include(o => o.Status).OrderByDescending(o => o.CreateDateTime)
                        .AsNoTracking();

                var orderses = orders.ToList();

                if (orderses.Count() <= 0)
                {
                    return null;
                }

                return orderses.Select(o => ToDTO(o)).ToArray();
            }
        }


        /// <summary>
        /// 更新订单数据
        /// </summary>
        /// <param name="orderDTO">订单Id</param>
        public void UpdateOrder(OrderDTO orderDTO)
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> baseService = new BaseService<Order>(context);
                Order order = baseService.GetById(orderDTO.Id);

                if (order == null)
                {
                    throw new ArgumentException(string.Format($"订单Id为：{order.Id}不存在"));
                }
                order.AddressId = orderDTO.AddressId;
                order.Amount = orderDTO.Amount;
                order.ExpressId = orderDTO.ExpressId;
                //order.Guid = orderDTO.Guid;
                order.StatusId = orderDTO.StatusId;
                order.LeaveWord = orderDTO.LeaveWord;
                order.PayWayId = orderDTO.PayWayId;
                order.ReceiptId = orderDTO.ReceiptId;

                //order.UserId = orderDTO.UserId;

                context.SaveChanges();
            }
        }

        private OrderDTO ToDTO(Order order)
        {
            OrderDTO dto = new OrderDTO();
            dto.Id = order.Id;
            dto.StatusName = order.Status.Name;
            dto.AddressId = order.AddressId;
            dto.Amount = order.Amount;
            dto.CreateDateTime = order.CreateDateTime;
            dto.Express = order.Express.Name;
            dto.ExpressId = order.ExpressId;
            dto.Guid = order.Guid;
            dto.StatusId = order.StatusId;
            dto.LeaveWord = order.LeaveWord;
            dto.PayWayId = order.PayWayId;
            dto.PayWayName = order.PayWay.Name;

            dto.ReceiptId = order.ReceiptId;
            dto.ReceiptName = order.Receipt.Name;

            if (order.Address != null)
            {
                dto.PhoneNum = order.Address.PhoneNum;
                dto.PostEmail = order.Address.PostEmail;
                dto.AreaId = order.Address.AreaId;
                string areaName = order.Address.Area.Name;
                string cityName = order.Address.Area.City.Name;
                string provinceName = order.Address.Area.City.Province.Name;
                provinceName = provinceName == cityName ? "" : provinceName;

                dto.ReciverAddress = order.Address.ReciverAddress;

                dto.CompleteAddress = provinceName + cityName + areaName + order.Address.ReciverAddress;

                dto.ReciverName = order.Address.ReciverName;
            }


            dto.UserId = order.UserId;
            dto.UserName = order.User.Name;
            return dto;
        }

        public long GetCountByDay()
        {
            using (LuShanTeaContext context = new LuShanTeaContext())
            {
                BaseService<Order> bs = new BaseService<Order>(context);
                DateTime time = DateTime.Now.AddHours(-24);
                return bs.GetAll().LongCount(e => e.StatusId == 5 && e.CreateDateTime > time) ;                
            }
        }
    }
}
